package com.dl.controller;

import com.dl.pojo.MyFile;
import com.dl.pojo.Page;
import com.dl.pojo.User;
import com.dl.pojo.vo.MyFileVo;
import com.dl.service.FileService;
import com.dl.service.UserService;
import com.dl.utils.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.*;
import java.util.HashMap;

/**
 * @author DL
 * @create 2021-03-23 14:26
 */
@Api(tags="文件操作接口")
@Controller
@RequestMapping("/file")
public class FileController {

    @Resource
    UserService userService;

    @Resource
    FileService fileService;

    //备用通用访问
    @GetMapping("/{str}")
    public String toStr(@PathVariable String str){
        return "/file/" + str;
    }

    @ApiOperation("跳转文件上传页面")
    @GetMapping("/upload")
    public String toUpload(){
        return "/file/upload";
    }

    @ApiOperation("跳转文件管理页面")
    @GetMapping("/fileManage")
    public String toFileManage(){
        return "file/fileManage";
    }

    @ApiOperation("跳转文件列表页面")
    @GetMapping("/fileList")
    public String toFileList(){
        return "file/fileList";
    }

    @ApiOperation("跳转视频播放页面")
    @GetMapping("/playVideo/{fileID}")
    public String toPlayVideo(@PathVariable Integer fileID, Model model){
        System.out.println("playVideo");
        MyFile myFile = fileService.queryFileById(fileID);
        model.addAttribute("myFile",myFile);

        return "file/playVideo";
    }

    @ApiOperation("文件管理页ajax分页")
    @ResponseBody
    @GetMapping(value = {"/json","/json/{currentPage}"})
    public Page<MyFile> queryStudentByLimitJson(@PathVariable(required = false) Integer currentPage){
        //如果为空则是第一次访问，默认访问第一页
        if (currentPage == null) {
            currentPage = 1;
        }
        System.out.println("currentPage=>" + currentPage);
        Page<MyFile> page = fileService.queryFileByLimit(currentPage, 10);
        page.setCurrentPage(currentPage);
        return page;
    }

    @ApiOperation("文件列表页ajax分页")
    @ResponseBody
    @GetMapping(value = {"/fileList/{tid}","/fileList/{tid}/{currentPage}"})
    public Page<MyFileVo> FileListJson(@PathVariable Integer tid, @PathVariable(required = false) Integer currentPage){
        //如果为空则是第一次访问，默认访问第一页
        if (currentPage == null) {
            currentPage = 1;
        }
        Page<MyFileVo> page = fileService.queryFileVoByLimit(tid, currentPage, 8);
        if (page != null) {
            page.setCurrentPage(currentPage);
            return page;
        }else {
            return null;
        }
    }

    @ApiOperation("上传头像")
    @ResponseBody
    @PostMapping("/avatar")
    public HashMap<String, String> avatar(@RequestParam("file") MultipartFile file, HttpServletRequest request, HttpSession session) {
        long startTime = System.currentTimeMillis();
        //存储返回消息
        System.out.println("file = " + file);
        HashMap<String, String> map = new HashMap<>();

        String fileName = file.getOriginalFilename();
        String type = file.getContentType();
        System.out.println("文件名 = " + fileName);
        String suffix = fileName.substring(fileName.lastIndexOf("."));
        System.out.println("文件后缀 = " + suffix);
        System.out.println("文件类型 = " + type);
        System.out.println("文件大小 = " + file.getSize() + "字节");
        //检测上传文件类型
        if (!TypeUtils.judgeImage(type)) {
            map.put("msg","类型错误");
            return map;
        }

        User user = (User) session.getAttribute(ConstantField.LOGIN_INFO);;//获得登录用户信息
        session.getAttribute(ConstantField.LOGIN_INFO);
        //String path = request.getServletContext().getRealPath("/avatar");//设置上传路径
        String path = System.getProperty("user.dir") + "\\avatar";//设置上传路径

        String userID = String.valueOf(user.getId());
        String realPath = path + "\\" + userID;//使用用户id作为路径防止重复

        //如果路径不存在则创建
        File filePath = new File(realPath);
        if (!filePath.exists()){
            boolean mkdirs = filePath.mkdirs();
            System.out.println("mkdir = " + mkdirs);
        }
        System.out.println("上传文件保存路径：" + realPath);

        //通过CommonsMultipartFile的方法直接写文件
        try {
            file.transferTo(new File(filePath + "\\avatar" + suffix));
            HashMap<String, String> userInfoMap = new HashMap<>();
            userInfoMap.put("uid",userID);
            userInfoMap.put("avatar","/avatar/" + userID + "/" + "avatar" + suffix);//写入数据库
            boolean b = userService.updateUserInfo(userInfoMap);
            if (b){
                //更新用户session信息
                user.setAvatar("/avatar/" + userID + "/" + "avatar" + suffix);
                session.setAttribute(ConstantField.LOGIN_INFO,user);
                map.put("msg","上传成功");
            }else {
                map.put("msg","上传失败-数据库写入异常");
            }
        } catch (IOException e) {
            map.put("msg","上传失败-文件写入异常");
            e.printStackTrace();
        }


        long endTime = System.currentTimeMillis();
        System.out.println("上传头像用时："+ (endTime - startTime) +"ms");
        return map;
    }


    @ApiOperation("上传文件，返回json")
    @ResponseBody
    @PostMapping("/upload")
    public HashMap<String, String> upload(@RequestParam("file") MultipartFile file,
                                          HttpServletRequest request,
                                          @RequestParam(required = false) String fileName,
                                          @RequestParam(required = false) String fileNote,
                                          Integer typeID) {
        //存储返回消息
        System.out.println("file = " + file);
        HashMap<String, String> map = new HashMap<>();
        // getName:获取表单中文件组件的名字 getOriginalFilename:获取上传文件的原名
        if ("".equals(fileNote)){ fileNote = "无"; }

        String originalFilename = file.getOriginalFilename();
        String type = file.getContentType();
        System.out.println("originalFilename = " + originalFilename + "，type = " + type);

        //如果文件为空直接返回文件上传页
        if ("".equals(originalFilename) || file.isEmpty()){
            map.put("msg","文件为空");
            return map;
        }
        //如果文件类型错误直接返回文件上传页
        if (!TypeUtils.judgeVideo(type)) {
            map.put("msg","类型错误");
            return map;
        }
        //如果有指定名称则使用指定名称否者使用文件原名称
        if ("".equals(fileName)){
            fileName = originalFilename;
        }else {
            String suffix = originalFilename.substring(originalFilename.lastIndexOf(".") + 1);
            fileName = fileName + "." + suffix;
        }
        System.out.printf("fileName：%s，fileNote：%s，typeID：%s\n",fileName,fileNote,typeID);//可以一次输出多个变量，注意顺序即可

        //String webPath = request.getServletContext().getRealPath("/upload");//上传文件保存路径

        String webPath = System.getProperty("user.dir") + "\\upload";//设置上传路径

        String uuid8 = UUIDUtils.getUUID8();//添加UUID防止重复
        webPath = webPath + "\\" + uuid8;//拼接路径
        System.out.println("webPath = " + webPath);
        File realPath = new File(webPath);

        long startTime = System.currentTimeMillis();

        String DBPath = "/upload/" + uuid8 + "/" + fileName;
        String cover = "/upload/" + uuid8 + "/cover.jpg";
        System.out.println("DBPath = " + DBPath + "，cover = " + cover);

        String filePath = realPath + "\\" + fileName;
        System.out.println("filePath = " + filePath);

        try {
            if (!realPath.exists()){
                realPath.mkdirs();//如果路径不存在则创建
            }
            file.transferTo(new File(filePath));//通过CommonsMultipartFile的transferTo方法直接写文件

            int videoTime = FfmpegUtils.getVideoTime(FfmpegUtils.ffmpegPath, filePath);//获取视频时长
            FfmpegUtils.getVideoCover(FfmpegUtils.ffmpegPath,filePath,"cover.jpg",videoTime);//获取视频封面
            int total = FfmpegUtils.getThumbnail(FfmpegUtils.ffmpegPath, filePath, videoTime);//获取视频进度条预览图

            //将文件信息写入数据库
            boolean b = fileService.addFile(new MyFile(fileName, DBPath, type, fileNote, cover, total, typeID));
            if (b) {
                map.put("msg","上传成功");
            }else {
                map.put("msg","上传失败-数据库写入异常");
            }
        }catch (Exception e){
            FileUtils.deleteFile(new File(webPath));
            map.put("msg","上传失败-文件写入异常");
        }

        long endTime = System.currentTimeMillis();
        System.out.println("文件上传时间："+ (endTime - startTime) +"ms");
        System.out.println("上传文件保存路径：" + filePath);
        return map;
    }

    @ApiOperation("删除文件")
    @ResponseBody
    @GetMapping("/del/{id}")
    public boolean del(@PathVariable int id, HttpServletRequest request) {
        boolean flag = false;
        System.out.println("del=>" + id);

        MyFile file = fileService.queryFileById(id);
        //获取数据库中文件路径
        String DBPath = file.getFilePath();
        System.out.println("获取数据库中文件路径 = " + DBPath);
        int lastIndexOf = DBPath.lastIndexOf("/");
        //去掉前面的'/'和文件名，得到上一级目录
        DBPath = DBPath.substring(1,lastIndexOf).replace("/","\\");
        System.out.println("去掉前面的'/'和文件名，得到上一级目录 = " + DBPath);
        //获取文件存储的真实路径前缀
        String prefix = System.getProperty("user.dir");//设置删除路径

        //String prefix = request.getServletContext().getRealPath("/");
        //拼接文件的完整真实路径
        String realPath = prefix + "\\" + DBPath;
        System.out.println("realPath = " + realPath);

        File realFile = new File(realPath);
        //使用工具类删除文件
        boolean delete = FileUtils.deleteFile(realFile);
        boolean deleteDB = fileService.deleteFile(id);

        System.out.println("文件删除 = " + delete);
        System.out.println("数据库删除 = " + deleteDB);
        if (delete && deleteDB){
            flag = true;
        }
        return flag;
    }

/*    @GetMapping("/download")
    public void upload(HttpServletRequest request, HttpServletResponse response) throws IOException {

        String path = request.getServletContext().getRealPath("/upload");
        String fileName = "123.jpg";

        //1.设置response响应头
        response.reset();//设置页面不缓存，刷新buffer
        response.setCharacterEncoding("utf-8");//字符编码
        response.setContentType("multipart/form-data");//二进制传输数据
        //设置响应头
        response.setHeader("Content-disposition",
                "attachment;filename=" + URLEncoder.encode(fileName,"UTF-8"));

        File file = new File(path,fileName);
        //2.读取文件，输入流
        InputStream inputStream = new FileInputStream(file);
        //3.写出文件，输出流
        OutputStream outputStream = response.getOutputStream();

        //创建缓冲区
        byte[] buffer = new byte[1024 * 1024];
        int len = 0;
        //4.写出文件
        while ((len=inputStream.read(buffer))>0){
            outputStream.write(buffer,0,len);
        }
        //关闭流
        outputStream.close();
        inputStream.close();
    }*/

}
